package jfds.clases.tokens;

public class Parser {
	Tokenizer tokenin;
	String Salida, Info, retorno, NombreCampo = "";
	boolean primeravez, notmatch, esasterizco;
	int tiporegistro=0, nivel88;
	Token t;
	public Parser (Tokenizer tokennizer){
		this.tokenin = tokennizer;
		primeravez=true;
	}
	
	//validar regla de FD
	public void reglaFD(){
		reglaEspacios();
		if (retorno != "NOOK"){
			match3(Token._spaces);
			if(esasterizco != true){
				match(Token._F);
				match(Token._D);
				match(Token._spaces);
				match2(Token.IDENTIFICADOR);
				}
			else {
				Salida ="";
			}
		}
	}
	
	//validar regla de espacios
	
	void reglaEspacios(){
		match(Token._spaces);
		retorno=tokenin.getSalida();
		if (retorno != "NOOK"){
			match(Token._spaces);
			match(Token._spaces);
			match(Token._spaces);
			match(Token._spaces);
			match(Token._spaces);	
		}else {
			Salida += retorno;
		}
	}
	
	// validar regla espacios mas identificador
	void reglaEspaciosEIdentificador(){
		match(Token._spaces);
		match(Token.IDENTIFICADOR);
	}
	
	// Validar regla Asteriscos o Espacios
	void reglaAsterisco(){
		match(Token._asterizco);
	}
	
	// validacion regla registros 01
	public void reglaRegistro01(){
		reglaEspacios();
		if (retorno != "NOOK"){
			match3(Token._spaces);
			if(esasterizco != true){
				match(Token._00);
				match(Token._01);
				match(Token._spaces);
				match4(Token._punto);
				tiporegistro = 3;
				}
			else {
				Salida ="";
			}
		}
	}
	// validacion del nombre del campo
	void reglaWKcampo(){
		match2(Token._W);
		match(Token._K);
		match(Token._guion);
		match(Token.IDENTIFICADOR);
	}
	
	//Valido que registro estoy leyendo
	public void ValidoCampos(){
		t = tokenin.nextToken();
		while (t.tipo != Token.EOF && t.tipo != Token._asterizco){
			switch ( t.tipo ) {
			case 0: match(Token._00);
			case 1:match(Token._spaces); 
						if (notmatch != true){
							match4(Token._punto);
							tiporegistro = 1;
						}
						else{
							Salida = "1" + t.Valor;
							tiporegistro = Integer.valueOf(Salida.toString());
							match4(Token._punto);
							//tiporegistro = 1;
							
						} 
						return;
			case 2: match4(Token._punto);
						tiporegistro = 2;
				        return;
			case 3: match4(Token._punto);
						tiporegistro = 3;
						return;
			case 4: match4(Token._punto);
						tiporegistro = 4;
						return;
			case 5: match4(Token._punto);
						tiporegistro = 5;
				        return;
			case 6: match4(Token._punto);
						tiporegistro = 6;
				        return;
			case 7: match4(Token._punto);
						tiporegistro = 7;
				        return;
			case 8: nivel88 = 1; 
					    tiporegistro = 8;
					    match4(Token._punto);
				        return;
			case 9: match4(Token._punto);
						tiporegistro = 9;
				        return;
			default : 
				t = tokenin.nextToken();
			}
		}
		if (t.tipo == Token._asterizco){
			tiporegistro = 99;
		}
	}
	//comprueba que el siguiente token sea del tipo esperado.
	 void match( int tokenTipo ) {
		 t = tokenin.nextToken();		 
		 if(t.tipo != tokenTipo){
			if (primeravez == true){
				Info   = "Se esperaba un " + Token.toString(tokenTipo) + "\n" ;
				Salida = Info;
				primeravez=false;
				notmatch = true;
			} else {
				Info    = "Se esperaba un " + Token.toString(tokenTipo) + "\n" ;
				Salida += Info;
			}
		 }else{
			 if (notmatch != true){
				 Salida = "OK";
			 }
		 }
	 }
	 
	 void match2( int tokenTipo ) {
		 t = tokenin.nextToken2();
		 if(t.tipo != tokenTipo){
			reglaEspaciosEIdentificador();	
		 }else{
			 tokenin.consumir();
			 if (notmatch != true){
				 Salida = "OK";
			 }
		 }
	 }
	 
	 void match3( int tokenTipo ) {
		 t = tokenin.nextToken2();
		 if(t.tipo != tokenTipo){
			esasterizco = true;
			reglaAsterisco();	
		 }else{
			 tokenin.consumir();
			 esasterizco = false;
			 if (notmatch != true){
				 Salida = "OK";
			 }
		 }
	 }
	void match4( int tokenTipo ) {
		 t = tokenin.bucle();
		 if (nivel88 == 1 && t.tipo == Token._08){
			 tiporegistro = 88;
		 }
		 while (t.tipo == Token._spaces && t.tipo != Token.EOF){
			 t = tokenin.bucle();
		 }
		 while(t.tipo != tokenTipo && t.tipo != Token.EOF){
			 NombreCampo += t.Valor;
			 t = tokenin.bucle();	
			}
		 NombreCampo+=t.Valor;
		 Salida = NombreCampo;
	}

	public String getSalida() {
		return Salida;
	}

	public void setSalida(String salida) {
		Salida = salida;
	}

	public String getRetorno() {
		return retorno;
	}

	public void setRetorno(String retorno) {
		this.retorno = retorno;
	}

	public int getTiporegistro() {
		return tiporegistro;
	}

	public void setTiporegistro(int tiporegistro) {
		this.tiporegistro = tiporegistro;
	}
}
